package com.hua.customviews.widget

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewParent
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.abs

/**
 * 垂直方向事件优先响应RV，水平方向放行
 * @author hua
 * date: 2023年1月31日
 */
class VerticalRecyclerView(private val mContext: Context, attrs: AttributeSet?, defStyleAttr: Int) :
    RecyclerView(mContext, attrs, defStyleAttr) {
    constructor(mContext: Context, attrs: AttributeSet?) : this(mContext, attrs, 0)
    constructor(mContext: Context) : this(mContext, null, 0)

    private var interceptStartX = 0f
    private var interceptStartY = 0f
    private var dispatchStartX = 0f
    private var dispatchStartY = 0f
    var enableIntercept: Boolean = true

    /**
     * 控制事件分发
     */
    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
                dispatchStartX = ev.rawX
                dispatchStartY = ev.rawY
                //当与外部可滑动组件嵌套时，内部的优先取得事件
                disallowParentIntercept(enableIntercept)
//                parent.parent.parent.parent.parent.parent.parent.parent.parent.parent.requestDisallowInterceptTouchEvent(enableIntercept)
            }

            MotionEvent.ACTION_MOVE -> {
                val deltaX = abs(ev.rawX - dispatchStartX)
                val deltaY = abs(ev.rawY - dispatchStartY)
                //水平滑动不拦截事件
                if (deltaX > deltaY) {
                    disallowParentIntercept(false)
                }
            }

            MotionEvent.ACTION_UP -> {
                //抬起时主动交还事件
                disallowParentIntercept(false)
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    /**
     * 所有父级控件的事件启用或禁用拦截
     */
    private var viewParent: ViewParent? = null
    private fun disallowParentIntercept(disallow: Boolean) {
        if (viewParent == null) viewParent = parent
        viewParent?.requestDisallowInterceptTouchEvent(disallow)
        if (viewParent?.parent != null && viewParent?.parent?.javaClass?.name != "com.android.internal.policy.DecorView") {
            //递归调用将所有父级控件(直到DecorView)的事件都禁用或启用
            viewParent = viewParent?.parent
            disallowParentIntercept(disallow)
        } else {
            //递归结束恢复到第一层parent
            viewParent = parent
        }
    }

    /**
     * 控制事件拦截
     */
    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
                interceptStartX = ev.rawX
                interceptStartY = ev.rawY
            }

            MotionEvent.ACTION_MOVE -> {
                val deltaX = abs(ev.rawX - interceptStartX)
                val deltaY = abs(ev.rawY - interceptStartY)
                //水平滑动不拦截事件
                if (deltaX > deltaY) {
                    return false
                }
            }

            MotionEvent.ACTION_UP -> {
            }
        }
        return super.onInterceptTouchEvent(ev)
    }

}